﻿namespace EFS.RC.CC.Tools.Schedulers
{
	/// <summary>
	/// ResumeRecordern
	/// </summary>
	internal class ResumeRecorder : EFS.Common.Async.AsyncRoot
	{
		#region Composition

		// conference id 
		private EFS.RC.CC.Tools.Recorders.Recorder recorder = null;

		// repeat
		private System.Threading.ManualResetEvent resumeRecorderEvent = null;

		#endregion

		#region Constructor
			
		/// <summary>
		/// Constructor
		/// </summary>
		/// <param name="recorder"></param>
		public ResumeRecorder(EFS.RC.CC.Tools.Recorders.Recorder recorder)
		{
			// set
			EFS.Common.Verify.Reference(recorder, "recorder");

			// set
			this.recorder = recorder;

			// register terminated delegate
			this.recorder.AsinkTerminatedDelegate.Register(OnRecorderTerminated);

			// create new wait event
			resumeRecorderEvent = new System.Threading.ManualResetEvent(false);

			// log
			EFS.EventLog.Log.LogInfo("ResumeRecorder", this);
		}

		#endregion

		#region Usage

		/// <summary>
		/// Describe this object into a nice formated string
		/// </summary>
		/// <returns></returns>
		public override System.String Describe()
		{
			return System.String.Format("EFS.RC.CC.Tools.Schedulers.ResumeRecorder [{0}]", recorder.Describe());
		}

		/// <summary>
		/// Begin startup
		/// </summary>
		public EFS.Common.Async.AsyncProcess Start()
		{
			// log
			EFS.EventLog.Log.LogInfo("BeginStartup", this);

			// begin
			return BeginAsyncProcess2(StartResumeRecorder, OnExecuteResumeRecorderComplete);
		}

		#endregion

		#region Runtime

		/// <summary>
		/// Unhandled exception
		/// </summary>
		/// <param name="ex"></param>
		protected override void OnException(System.Exception ex)
		{
			// check
			EFS.Common.Verify.Reference(ex, "ex");

			// log
			EFS.EventLog.Log.LogException(ex, this);
		}

		#endregion

		#region Execute

		/// <summary>
		/// ExecuteResumeRecorder
		/// </summary>
		private void StartResumeRecorder()
		{
			// log
			EFS.EventLog.Log.LogInfo("ExecuteResumeRecorder", this);

			// check wait event
			if (!resumeRecorderEvent.WaitOne(new System.TimeSpan(0, 0, EFS.RC.CC.Config.Settings.ResumeRecorderAfterSeconds)))
			{
				// resume
				recorder.BeginResume();
			}
		}

		/// <summary>
		/// Customer service office conference terminated
		/// </summary>
		/// <param name="recorder"></param>
		private void OnRecorderTerminated(EFS.RC.CC.Tools.Recorders.Recorder recorder)
		{
			// check
			EFS.Common.Verify.Reference(recorder, "recorder");

			// check mine
			EFS.Common.Verify.Condition(this.recorder.Equals(recorder), "Terminated hunter is different");

			// set
			resumeRecorderEvent.Set();

			// close
			BeginAsyncProcess2(CloseResumeRecorderEvent);
		}

		/// <summary>
		/// Close event
		/// </summary>
		private void CloseResumeRecorderEvent()
		{
			// set event
			resumeRecorderEvent.Close();
		}

		/// <summary>
		/// ExecuteResumeRecorder complete
		/// </summary>
		/// <param name="ar"></param>
		private void OnExecuteResumeRecorderComplete(EFS.Common.Async.AsyncProcess ap)
		{
			// log
			EFS.EventLog.Log.LogInfo("OnExecuteResumeRecorderComplete", this);

			try
			{
				// check
				ap.Throw();

				// log
				EFS.EventLog.Log.LogInfo("OnExecuteResumeRecorderComplete SUCCCESS", this);
			}
			catch (System.Exception ex)
			{
				// log
				EFS.EventLog.Log.LogException(ex, this);
			}
		}

		#endregion
	}
}
